//
// Created by mio on 25-4-11.
//

#ifndef TASKSCHEDULER_H
#define TASKSCHEDULER_H

#include <mutex>
#include <atomic>
#include <cstdint>

#include "Channel.h"
#include "Timer.h"


/**
 * @brief 任务调度器的抽象基类。
 * 定义了一个事件循环的基本框架，包含定时器管理和 I/O 事件处理的接口。
 * 具体的 I/O 多路复用机制由派生类实现。
 */
class TaskScheduler
{
public:
    TaskScheduler(int id = 1);
    virtual ~TaskScheduler();
    /**
     * @brief 启动事件循环。
     * 该方法会阻塞，直到 Stop() 被调用。
     */
    void Start();
    /**
     * @brief 请求停止事件循环。
     * 设置停止标志，事件循环将在下一次迭代检查时退出。
     */
    void Stop();
    /**
     * @brief 添加一个定时器任务。
     * @param event 定时器触发时执行的回调函数。
     * @param msec 定时器的间隔或延迟（毫秒）。
     * @return 新添加的定时器的唯一 ID (TimerId)。
     */
    TimerId AddTimer(const TimerEvent& event, uint32_t mesc);
    /**
     * @brief 移除一个指定 ID 的定时器任务。
     * @param timerId 要移除的定时器的 ID。
     */
    void RemoveTimer(TimerId timerId);
    /**
     * @brief 更新（添加或修改）一个 Channel 的监听状态。
     * 派生类需要实现此方法，将 Channel 的事件注册到底层的 I/O 多路复用机制中。
     * @param channel 要更新的 Channel 对象的智能指针。
     */
    virtual void UpdateChannel(ChannelPtr channel) {}
    /**
     * @brief 移除一个 Channel 的监听。
     * 派生类需要实现此方法，从底层的 I/O 多路复用机制中移除对该 Channel 的监听。
     * @param channel 要移除的 Channel 对象的智能指针。
     */
    virtual void RemoveChannel(ChannelPtr channel) {}
    /**
     * @brief 处理一次 I/O 事件。
     * 派生类需要实现此方法，调用底层的 I/O 多路复用函数（如 epoll_wait, select, poll）
     * 来等待并处理发生的 I/O 事件。
     * @return 通常返回一个布尔值或状态码，指示是否成功处理了事件或是否应该继续循环。
     */
    virtual bool HandleEvent(int timeout) { return false; }
    /**
     * @brief 获取调度器的 ID。
     * @return 调度器的 ID。
     */
    inline int GetId() const { return id_; }

private:
    int id_ = 0;                    // 调度器的 ID
    std::mutex mtx_;                // 互斥锁 (在基类中未使用，可能为派生类或未来准备)
    TimerQueue timer_queue_;        // 管理定时器任务的队列实例
    std::atomic_bool is_shutdown_;  // 原子布尔标志，用于线程安全地控制循环的停止
};

using TaskSchedulerPtr = std::shared_ptr<TaskScheduler>;

#endif //TASKSCHEDULER_H
